package com.ycwl.freetv.utils;

import android.os.Environment;
import android.os.StatFs;
import android.util.Log;

import com.ycwl.library.AssetsListManager;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

public class FileUtils {
    public static List<File> fetchFiles(String directoryPath) {
        return fetchFiles(directoryPath, "\".*\\\\.(jpg|jpeg|png|gif|mp4|avi|mov|mkv|mpeg|3gp)$\"");
    }
    public static List<File> fetchFiles(String directoryPath, String regex) {
        File directory = new File(directoryPath);
        FilenameFilter videoFilter = new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.toLowerCase().matches(regex);
            }
        };

        File[] files = directory.listFiles(videoFilter);
        List<File> videoFiles = new ArrayList<>();
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    videoFiles.add(file);
                }
            }
        }
        return videoFiles;
    }
    public static String getSha1(File file) {
        MessageDigest digest = null;
        FileInputStream fis = null;
        try {
            digest = MessageDigest.getInstance("SHA-1");
            fis = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int read = 0;
            while ((read = fis.read(buffer)) != -1) {
                digest.update(buffer, 0, read);
            }
            byte[] sha1Bytes = digest.digest();
            return bytesToHex(sha1Bytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static String GetFileSHA1ByPath(String filePath) {
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(filePath);
            byte[] buffer = new byte[1024];
            MessageDigest digest = MessageDigest.getInstance("SHA-1");

            int read = inputStream.read(buffer);
            while (read != -1) {
                digest.update(buffer, 0, read);
                read = inputStream.read(buffer);
            }

            byte[] sha1Bytes = digest.digest();
            return bytesToHex(sha1Bytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static String getSha1(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(str.getBytes());
            return bytesToHex(digest.digest());
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }


    private static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }



    public static String readTextFromFile(String filePath) {
        String res = "";

        try {
            File file = new File(filePath);
            if (!file.exists()) {
                return "";
            }
            FileInputStream fin = new FileInputStream(file);
            int length = fin.available();
            byte[] buffer = new byte[length];
            fin.read(buffer);
            res = new String(buffer);
            fin.close();
        } catch (IOException ignored) {
        }
        return res;
    }

    public static List<String> scanFileInByDir(String path, String regex, int deep) {
        List<String> pathList = new ArrayList<>();
        if (deep <= 0) {
            return pathList;
        }
        File file = new File(path);
        List<String> list = scanFileInByDir(file, regex ,deep);
        if (list.size() > 0) {
            pathList.addAll(list);
        }
        return pathList;
    }
    public static List<String> scanFileInByDir(File directory, String regex, int deep) {
        List<String> pathList = new ArrayList<>();
        if (deep <= 0) {
            return pathList;
        }
        if (directory != null && directory.exists() && directory.isDirectory()) {
            File[] fileArray = directory.listFiles();
            if (fileArray == null) {
                return pathList;
            }

            for (File file : fileArray) {
                if (file.isDirectory()) {
                    List<String> list = scanFileInByDir(file,regex, --deep);
                    if (list.size() > 0) {
                        pathList.addAll(list);
                    }
                } else if (file.getName().matches(regex)) {
                    pathList.add(file.getAbsolutePath());
                }
            }
        }
        return pathList;
    }

    public static boolean copyFile(File sourceFile, File destFile) {
        FileInputStream inputStream = null;
        FileOutputStream outputStream = null;
        try {
            inputStream = new FileInputStream(sourceFile);
            outputStream = new FileOutputStream(destFile);

            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, length);
            }

            inputStream.close();
            outputStream.close();
        } catch (IOException e) {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ex) {
                    return false;
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException ex) {
                    return false;
                }
            }
            return false;
        }

        return true;
    }

    public static void deleteFile(String filePath) {
        File file = new File(filePath);
        deleteFile(file);
    }

    public static void deleteFile(File file) {
        if (file.exists()) {
            if (file.delete()) {
                Log.i("AssetsListManager", "delete success; "+ file.getAbsolutePath());
            } else {
                Log.i("AssetsListManager", "delete fail; "+ file.getAbsolutePath());
            }
        }
    }

    public static long calculateUncompressedSize(String zipFilePath) throws IOException {
        FileInputStream fis = new FileInputStream(zipFilePath);
        ZipInputStream zis = new ZipInputStream(fis);
        ZipEntry entry;
        long size = 0;

        while ((entry = zis.getNextEntry()) != null) {
            size += entry.getSize();
            zis.closeEntry();
        }

        zis.close();
        return size;
    }

    public static HashMap<String,AssetsListManager.Assets> getAllAssetsInZip(String path) {
        HashMap<String,AssetsListManager.Assets> hashMap = new HashMap<>();
        File zipFile = new File(path);
        ZipFile zfile = null;
        try {
            zfile = new ZipFile(zipFile);
            Enumeration<? extends ZipEntry> zList = zfile.entries();
            ZipEntry ze = null;
            byte[] buf = new byte[1024];
            while (zList.hasMoreElements()) {
                ze = (ZipEntry) zList.nextElement();
                if (ze.isDirectory()) {
                    continue;
                }
                String tempFileName = ze.getName();
                InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
                MessageDigest digest = MessageDigest.getInstance("SHA-1");

                int readLen = 0;
                while ((readLen = is.read(buf, 0, 1024)) != -1) {
                    digest.update(buf, 0, readLen);
                }
                is.close();
                byte[] sha1Bytes = digest.digest();
                String sha1 = bytesToHex(sha1Bytes);
                if (hashMap.containsKey(sha1)) {
                    continue;
                }
                hashMap.put(sha1,new AssetsListManager.Assets(sha1,path,tempFileName));
            }
            zfile.close();
        } catch (IOException e) {
            if (zfile != null) {
                try {
                    zfile.close();
                } catch (IOException ignored) {

                }
            }
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }

        return hashMap;
    }
    public static String getFileExtension(String fileName) {
        if (fileName == null) {
            return null;
        }
        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex == -1) {
            return null;
        }
        return fileName.substring(dotIndex + 1);
    }


}
